/*
 * Copyright 2010-2012 Susanta Tewari. <freecode4susant@users.sourceforge.net>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package coalescent.is.nb.jobs;

import coalescent.data.meta.MetaInf_K69Data;
import com.jidesoft.hints.ListDataIntelliHints;
import com.jidesoft.swing.DefaultOverlayable;
import commons.nb.jobs.properties.editors.Base_ComboIE;
import commons.nb.jobs.properties.editors.Base_ExPE_IFactory;
import commons.nb.jobs.properties.editors.Double_PE_GoodStart;
import commons.util.FormatUtil;
import commons.util.GUIUtil;
import jide.IconS;
import jide.OLs;
import org.openide.explorer.propertysheet.InplaceEditor;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.math.BigDecimal;

import static com.google.common.collect.Lists.newArrayList;

/**
 * @since since
 * @version version
 * @author Susanta Tewari
 * @history Created on 12/30/13.
 */
public class ThetaExactProb_ExPE_IFactory extends Base_ExPE_IFactory<MetaInf_K69Data> {

    public ThetaExactProb_ExPE_IFactory() {
        setDelegate(new Double_PE_GoodStart());
    }

    @Override
    protected InplaceEditor buildInplace(MetaInf_K69Data inplaceData) {
        return new Theta_ComboIE(inplaceData);
    }

    private static class Theta_ComboIE extends Base_ComboIE<MetaInf_K69Data> {

        private JTextField theta_field;
        private JLabel lHood_label;
        private Double selectedValue = 1.0;

        protected Theta_ComboIE(MetaInf_K69Data data) {
            super(data);
        }

        @Override
        protected Double getSelectedValue() {
            return selectedValue;
        }

        @Override
        protected JPanel make_comp_impl(JDialog dialog, final MetaInf_K69Data metaInf) {    // init control & data

            theta_field = of_Hints_OL(newArrayList((metaInf.getRates())));    // overlayable w/ hints

            theta_field.getDocument().addDocumentListener(new DocumentListener() {

                @Override
                public void insertUpdate(DocumentEvent e) {
                    thetaFieldChanged(metaInf);
                }
                @Override
                public void removeUpdate(DocumentEvent e) {
                    thetaFieldChanged(metaInf);
                }
                @Override
                public void changedUpdate(DocumentEvent e) {
                    thetaFieldChanged(metaInf);
                }

            });    // updates lhood label

            //J- <editor-fold desc=" overlay Info icon">
            final JLabel infoIcon = new JLabel(IconS.info());
            infoIcon.setToolTipText("Click for Help...");
            infoIcon.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));

            infoIcon.addMouseListener(new MouseAdapter() {
                final String text     =
                        "<HTML>" +
                           "Pressing <b>down-arrow or typing</b> shows rates <br>" +
                           "with known <b>exact likelihood</b>." +
                        "</HTML>";
                @Override
                public void mousePressed(MouseEvent e) {
                    JPopupMenu popup = new JPopupMenu();
                    JLabel label = new JLabel(text);
                    label.setOpaque(true);
                    label.setBackground(Color.white);
                    label.setBorder(new EmptyBorder(5,5,5,5));
                    popup.add(label);
                    popup.show(e.getComponent(), e.getX(), e.getY() + 25);
                }
            });//J+


            DefaultOverlayable theta_field_OL = new DefaultOverlayable(theta_field, infoIcon,
                                                    DefaultOverlayable.RIGHT);

            theta_field_OL.setOverlayLocationInsets(new Insets(0, 0, -3, 18));
            theta_field_OL.setOverlayVisible(true);    // </editor-fold>


            // pack up
            JPanel panel = new JPanel(new GridLayout(2, 1));

            panel.add(theta_field_OL);
            panel.add(lHood_label = of_label());

            return panel;
        }

        private void thetaFieldChanged(MetaInf_K69Data metaInf) {

            final String text = theta_field.getText();

            if (!text.isEmpty() && isDouble(text)) {

                final double theta     = Double.parseDouble(text);
                final boolean contains = metaInf.contains(theta);

                this.selectedValue = theta;

                if (contains) {

                    final BigDecimal prob = metaInf.getProb(theta);

                    lHood_label.setText("<html>Exact LHood: " + FormatUtil.format(prob)
                                        + "</html>");

                } else {
                    lHood_label.setText("");
                }
            }
        }

        private JLabel of_label() {

            final JLabel jLabel = new JLabel();

            jLabel.setOpaque(true);
            jLabel.setForeground(Color.black);

            return jLabel;
        }

        private boolean isDouble(String value) {

            try {

                Double.parseDouble(value);

                return true;

            } catch (NumberFormatException e) {
                return false;
            }
        }

        /**
         * @param doubles mutation rates
         * @return overlayable textfield with intelli hints
         */
        private JTextField of_Hints_OL(java.util.List<Double> doubles) {

            JTextField field = OLs.of_JTextField();

            new ListDataIntelliHints<>(field, doubles);

            return field;
        }

        public static void main(String[] args) {


            // show popup
            final JPanel panel = new JPanel();
            JButton b1         = new JButton("Show Popup");


            // data
            MetaInf_K69Data metaInf = new MetaInf_K69Data();

            metaInf.addProb(1.0, new BigDecimal(0.10));
            metaInf.addProb(1.5, new BigDecimal(0.15));
            metaInf.addProb(2.0, new BigDecimal(0.20));
            metaInf.addProb(2.5, new BigDecimal(0.25));
            metaInf.addProb(3.0, new BigDecimal(0.30));


            // editor
            final Theta_ComboIE editor = new Theta_ComboIE(metaInf);
            final JDialog dialog       = editor.getDialog();

            b1.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {

                    final JButton source = (JButton) e.getSource();
                    final Point point    = source.getLocationOnScreen();

                    point.translate(0, source.getHeight());
                    dialog.setLocation(point);
                    dialog.setVisible(true);


                    // selected value
                    System.out.println("Selected Value: " + editor.getSelectedValue());
                }

            });
            panel.add(b1);
            GUIUtil.displayGUI("", panel);
        }
    }
}
